import clsx from 'clsx'
import type { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactNode } from 'react'

type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'link'
type ButtonSize = 'sm' | 'md' | 'lg'

type BaseProps = {
  variant?: ButtonVariant
  size?: ButtonSize
  icon?: ReactNode
  iconPosition?: 'left' | 'right'
}

type ButtonAsButton = BaseProps & ButtonHTMLAttributes<HTMLButtonElement> & { as?: 'button' }
type ButtonAsLink = BaseProps & AnchorHTMLAttributes<HTMLAnchorElement> & { as: 'a'; href: string }

type ButtonProps = ButtonAsButton | ButtonAsLink

const baseStyles =
  'inline-flex items-center justify-center gap-2 font-semibold transition focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-60 transform-gpu duration-200 hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98]'

const variantStyles: Record<ButtonVariant, string> = {
  primary:
    'rounded-2xl bg-gradient-to-r from-blush-500 to-lavender-500 text-white shadow-md hover:shadow-lg focus-visible:ring-blush-200 focus-visible:ring-offset-white',
  secondary:
    'rounded-2xl border border-slate-200 bg-white text-slate-600 hover:border-blush-200 hover:text-blush-500 focus-visible:ring-blush-200 focus-visible:ring-offset-white',
  ghost: 'rounded-2xl text-slate-500 hover:bg-slate-100 focus-visible:ring-slate-200 focus-visible:ring-offset-white',
  link: 'rounded-full px-0 py-0 text-blush-500 hover:text-blush-400 focus-visible:ring-transparent',
}

const sizeStyles: Record<ButtonSize, string> = {
  sm: 'px-3 py-1.5 text-xs',
  md: 'px-4 py-2 text-sm',
  lg: 'px-5 py-2.5 text-base',
}

export const Button = ({
  variant = 'primary',
  size = 'md',
  icon,
  iconPosition = 'left',
  as = 'button',
  children,
  className,
  ...props
}: ButtonProps) => {
  const Icon = icon ? <span className="flex h-4 w-4 items-center justify-center">{icon}</span> : null
  const content = (
    <span className="inline-flex items-center gap-2">
      {iconPosition === 'left' && Icon}
      <span>{children}</span>
      {iconPosition === 'right' && Icon}
    </span>
  )

  if (as === 'a') {
    const linkProps = props as AnchorHTMLAttributes<HTMLAnchorElement>
    return (
      <a
        className={clsx(baseStyles, variantStyles[variant], sizeStyles[size], className)}
        {...linkProps}
      >
        {content}
      </a>
    )
  }

  return (
    <button className={clsx(baseStyles, variantStyles[variant], sizeStyles[size], className)} {...(props as ButtonHTMLAttributes<HTMLButtonElement>)}>
      {content}
    </button>
  )
}

export default Button
